# coding:utf-8
import json
import os
import re
import time

from common.consts import ROLES, FIRSTLEVELS, SECONDLEVELS
from common.error import UserExistsError, RoleError, LevelError, CountError, NegativeNumberError
from common.utils import check_file, timestamp_to_string


class Base(object):
    def __init__(self, user_json, gift_json):
        self.user_json = user_json
        self.gift_json = gift_json
        # 调用检查user_json文件方法
        self.__check_user_json()
        # 调用检查gift_json文件方法
        self.__check_gift_json()
        # 初始化奖品数据结构
        self.__init_gifts()

    # 检查user_json
    def __check_user_json(self):
        check_file(self.user_json)

    # 检查gift_json
    def __check_gift_json(self):
        check_file(self.gift_json)

    # 新增用户
    def __write_user(self, **user):
        if 'userName' not in user:
            raise ValueError('用户名不能为空')
        if 'userPassword' not in user:
            raise ValueError('密码不能为空')
        if 'roles' not in user:
            raise ValueError('角色不能为空')
        if re.search('\d', user['userPassword']) is None:
            raise ValueError('密码为纯数字')

        # 设置默认值
        user['createTime'] = time.time()
        user['updateTime'] = time.time()
        user['status'] = True
        user['gifts'] = []
        users = self.__read_users()

        users.update(
            {user['userName']: user}
        )

        self.__save(users, self.user_json)

    # 查询用户方法
    def __read_users(self, time_to_str=False):
        with open(self.user_json, 'r') as f:
            data = json.loads(f.read())

        # 是否将时间格式化
        if time_to_str == True:
            for k, v in data.items():
                v['createTime'] = timestamp_to_string(v['createTime'])
                v['updateTime'] = timestamp_to_string(v['updateTime'])
                data[k] = v
        return data

    # 修改用户
    def __update_user(self, userName, role, status):
        # 查询所有用户
        users = self.__read_users()
        # 通过用户名获取要修改的用户
        user = users.get(userName)
        # 如果用户不存在，就直接返回
        if not user:
            return False
        # 如果角色不存在
        if role not in ROLES:
            raise RoleError('角色只有admin(管理员)， normal（普通用户）） %s' % role)
        user['status'] = status
        user['role'] = role
        user['updateTime'] = time.time()
        users[userName] = user

        self.__save(users, self.user_json)
        return True

    # 删除用户
    def __delete_user(self, userName):
        users = self.__read_users()
        user = users.get(userName)
        if not user:
            return False

        delete_user = users.pop(userName)
        self.__save(users, self.user_json)
        return delete_user

    # 查询奖品
    def __read_gifts(self):
        with open(self.gift_json) as f:
            data = json.loads(f.read())
        return data

    def __init_gifts(self):
        data = {
            'level1': {
                'level1': {},
                'level2': {},
                'level3': {}
            },
            'level2': {
                'level1': {},
                'level2': {},
                'level3': {}
            },
            'level3': {
                'level1': {},
                'level2': {},
                'level3': {}
            },
            'level4': {
                'level1': {},
                'level2': {},
                'level3': {}
            }
        }
        gifts = self.__read_gifts()
        # 如果有数据，就不进行初始化
        if len(gifts) != 0:
            return

        self.__save(data, self.gift_json)
        return True

    # 增加奖品
    def __write_gift(self, first_level, sencond_level, gift_name, gift_count):
        if first_level not in FIRSTLEVELS:
            raise LevelError('该一级奖池不存在 %s ' % first_level)
        if sencond_level not in SECONDLEVELS:
            raise LevelError('该二级奖池不存在 %s ' % sencond_level)
        gifts = self.__read_gifts()

        # 先从一级奖池取到二级奖池
        current_gift_pool = gifts[first_level]
        # 再从二级奖池取到奖品池
        current_second_gift_pool = current_gift_pool[sencond_level]

        if gift_count <= 0:
            gift_count = 1

        # 奖品是否已存在
        if gift_name in current_second_gift_pool:
            current_second_gift_pool[gift_name]['count'] = current_second_gift_pool[gift_name]['count'] + gift_count
        else:
            current_second_gift_pool[gift_name] = {
                'name': gift_name,
                'count': gift_count
            }

        # 把奖品放回到二级奖池
        current_gift_pool[sencond_level] = current_second_gift_pool
        # 再将二级放回到一级
        gifts[first_level] = current_gift_pool
        self.__save(gifts, self.gift_json)

    def __gift_update(self, userName, first_level, second_level,
                      gift_name, gift_count=1):
        assert isinstance(gift_count, int), '数量是整数类型'
        data = self.__check_and_getgift(first_level, second_level, gift_name)

        if data == False:
            return data
        # 获取一级奖池
        current_gift_pool = data.get('level_one')
        # 获取二级奖池
        current_second_gift_pool = data.get('level_two')
        # 获取奖品
        current_gift = current_second_gift_pool[gift_name]
        # 获取整个奖池
        gifts = data.get('gifts')

        # 调用查询用户方法，获取全部用户
        users = self.__read_users()
        # 通过传入的用户名获取用户
        user = users.get(userName)
        # 获取角色
        roles = user.get('roles')
        # 判断角色
        if roles == 'admin':
            if gift_count <= 0:
                raise ValueError('礼物数不能为0')
            current_gift['count'] = gift_count
        else:
            if current_gift['count'] - gift_count < 0:
                raise NegativeNumberError('没有奖品啦！')
            current_gift['count'] -= gift_count
            # 奖品加入到用户里
            user['gifts'].append(gift_name)
            users[user.get("userName")] = user
            self.__save(users, self.user_json)

        # 奖品放到二级奖池
        current_second_gift_pool[gift_name] = current_gift
        # 二级奖池放到一级奖池
        current_gift_pool[second_level] = current_second_gift_pool
        # 一级奖池加到整个奖品结构中
        gifts[first_level] = current_gift_pool
        # 添加到JSON文件中
        self.__save(gifts, self.gift_json)

    # 删除奖品
    def __delete_gift(self, first_level, second_level,
                      gift_name):
        data = self.__check_and_getgift(first_level, second_level, gift_name)

        if data == False:
            return data

        current_gift_pool = data.get('level_one')
        current_second_gift_pool = data.get('level_two')
        gifts = data.get('gifts')
        # 移除奖品
        delete_gift_data = current_second_gift_pool.pop(gift_name)
        # 二级放一级
        current_gift_pool[second_level] = current_second_gift_pool
        # 一级放总体
        gifts[first_level] = current_gift_pool
        self.__save(gifts, self.gift_json)
        return delete_gift_data

    # 判断奖品并获得
    def __check_and_getgift(self, first_level, second_level, gift_name):
        if first_level not in FIRSTLEVELS:
            raise LevelError('该一级奖池不存在 %s ' % first_level)
        if second_level not in SECONDLEVELS:
            raise LevelError('该二级奖池不存在 %s ' % second_level)

        gifts = self.__read_gifts()

        # 获取一级奖池
        level_one = gifts[first_level]
        # 获取二级奖池
        level_two = level_one[second_level]
        # 如果奖品不在奖池内直接返回False
        if gift_name not in level_two:
            return False

        return {
            'level_one': level_one,
            'level_two': level_two,
            'gifts': gifts
        }

    # 写入到json文件
    def __save(self, data, path):
        json_data = json.dumps(data)
        with open(path, 'w') as f:
            f.write(json_data)


if __name__ == '__main__':
    user_path = os.path.join(os.path.abspath(os.path.dirname(os.path.dirname(__file__))), 'storage', 'user.json')
    gift_path = os.path.join(os.path.abspath(os.path.dirname(os.path.dirname(__file__))), 'storage', 'gift.json')
    base = Base(user_json=user_path, gift_json=gift_path)
    base._Base__gift_update(userName='jie', first_level='level1', second_level='level1',
                            gift_name='iPhone14 Pro Max', gift_count=66)
